package me.pplay.playtalk.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.LinkedHashMap;

import me.pplay.playtalk.data.Globals;
import me.pplay.playtalk.net.HttpUtil;
import me.pplay.playtalk.util.fileUtil.FileUtil;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;


public class AsyncImageLoader {
	private LinkedHashMap<String, SoftReference<Bitmap>> imageCache = new LinkedHashMap<String, SoftReference<Bitmap>>();
	public AsyncImageLoader() {}

	// 从缓存中读
	public Bitmap loadBitmap(final String imageUrl, final ImageCallback callback) {
		if(imageUrl == null) return null;
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
			if (softReference.get() != null) {
				return softReference.get();
			}
		}
		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				callback.imageLoaded((Bitmap) msg.obj, imageUrl);
			}
		};

		new Thread() {
			public void run() {
				Bitmap bitmap = loadImageFromUrl(imageUrl);
				if (bitmap != null)
					imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
				handler.sendMessage(handler.obtainMessage(0, bitmap));
			};
		}.start();
		return null;
	}

	/**
	 * 下载图片保存SD卡 并返回保存路径
	 * 
	 * @param imageUrl
	 * @return
	 */
	public String getImageToSd(String imageUrl) {
		try {
			String md5Str = MD5.toMD5(imageUrl);
			String path = Globals.FILE_PATH_CACHE_IMAGE + md5Str;
			if (FileUtil.isExistFile(path)) {
				return "file://" + path;
			}
			InputStream inputStream = HttpUtil.doGet(imageUrl);
			if (inputStream != null) {
				byte[] b = InputStreamToByte(inputStream);
				FileUtil.writeToFile(path, b);
				return "file://" + path;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	protected Bitmap loadImageFromUrl(String imageUrl) {
		String mad5Str 	= MD5.toMD5(imageUrl);
		String path 	= Globals.FILE_PATH_CACHE_IMAGE + mad5Str;
		Bitmap map 		= null;
		InputStream inputStream = null;
		try {
			if (FileUtil.isExistFile(path)) {
				File file = new File(path);
				FileInputStream fs = null;
				try {
					fs = new FileInputStream(file);
					map = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, null);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}finally {
					try {
						fs.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			} else {
				inputStream = HttpUtil.doGet(imageUrl);
				if (inputStream != null) {
					byte[] b = InputStreamToByte(inputStream);
					FileUtil.writeToFile(path, b);
					try {
						map = BitmapFactory.decodeByteArray(b, 0, b.length, null);
					} catch (Exception e) {
						e.printStackTrace();
						return null;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			closeInputStream(inputStream);
		}
		
		return map;
	}

	private void closeInputStream(InputStream input) {
		try {
			if (input != null) {
				input.close();
				input = null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	public byte[] InputStreamToByte(InputStream iStrm) throws IOException {
		if (iStrm != null) {
			int ch;
			ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
			while ((ch = iStrm.read()) != -1) {
				bytestream.write(ch);
			}
			byte imgdata[] = bytestream.toByteArray();
			bytestream.flush();
			bytestream.close();
			return imgdata;
		}
		return null;
	}

	
	public interface ImageCallback {
		public void imageLoaded(Bitmap imageBitmap, String imageUrl);
	}

	public void recycleImageCache() {
		if (imageCache != null && imageCache.size() > 0) {
			imageCache.clear();
			imageCache = null;
			System.gc();
		}
	}

}